package com.example.wisdomclassroomapi.common.util;

import lombok.extern.slf4j.Slf4j;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

/**
 * 消息摘要工具类
 */
@Slf4j
public class MessageDigestUtil {
    // MD5算法名常量
    public static final String ALGORITHM_MD5 = "MD5";
    // Sha256算法名常量
    public static final String ALGORITHM_SHA256 = "SHA-256";
    // Sha512算法名常量
    public static final String ALGORITHM_SHA512 = "SHA-512";

    /**
     * MD5摘要返回Base64格式字符串方法
     * @param message 消息
     * @return String
     */
    public String md5WithBase64(String message) {
        return digestWithBase64(message, ALGORITHM_MD5);
    }

    /**
     * MD5摘要返回Hex格式字符串方法
     * @param message 消息
     * @return String
     */
    public String md5WithHex(String message) {
        return digestWithHex(message, ALGORITHM_MD5);
    }

    /**
     * SHA256摘要返回Base64格式字符串方法
     * @param message 消息
     * @return String
     */
    public String sha256WithBase64(String message) {
        return digestWithBase64(message, ALGORITHM_SHA256);
    }

    /**
     * SHA256摘要返回Hex格式字符串方法
     * @param message 消息
     * @return String
     */
    public String sha256WithHex(String message) {
        return digestWithHex(message, ALGORITHM_SHA256);
    }

    /**
     * SHA512摘要返回Base64格式字符串方法
     * @param message 消息
     * @return String
     */
    public String sha512WithBase64(String message) {
        return digestWithBase64(message, ALGORITHM_SHA512);
    }

    /**
     * SHA512摘要返回Hex格式字符串方法
     * @param message 消息
     * @return String
     */
    public String sha512WithHex(String message) {
        return digestWithHex(message, ALGORITHM_SHA512);
    }

    /**
     * 通用Sha摘要方法
     * @param message 消息
     * @param algorithm 算法名
     * @return byte[]
     */
    private byte[] digest(String message, String algorithm) {
        byte[] result = null;
        try{
            MessageDigest  messageDigest = MessageDigest.getInstance(algorithm);
            messageDigest.update(message.getBytes());
            result = messageDigest.digest();
        } catch (NoSuchAlgorithmException e) {
            log.error("No such algorithm: {}", algorithm, e);
        }
        return result;
    }

    /**
     * 通用消息摘要返回Base64格式字符串方法
     * @param message 消息
     * @param algorithm 算法名
     * @return String
     */
    private String digestWithBase64(String message, String algorithm) {
        byte[] digest = digest(message, algorithm);
        String result = null;
        if(digest != null) {
            result = Base64.getEncoder().encodeToString(digest);
        }
        return result;
    }

    /**
     * 通用消息摘要返回Hex格式字符串方法
     * @param message 消息
     * @param algorithm 算法名
     * @return String
     */
    private String digestWithHex(String message, String algorithm) {
        byte[] digest = digest(message, algorithm);
        String result = null;
        if(digest != null) {
            StringBuilder stringBuilder = new StringBuilder();
            for (byte b : digest) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    stringBuilder.append('0');
                }
                stringBuilder.append(hex);
            }
            result = stringBuilder.toString();
        }
        return result;
    }
}
